package com.centanet.framework.network;

import android.support.v4.util.ArrayMap;
import android.text.TextUtils;

import com.android.volley.Request;
import com.centanet.framework.interfaces.ILoggerTag;
import com.centanet.framework.interfaces.IResponseListener;
import com.google.gson.Gson;
import com.orhanobut.logger.Logger;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;

/**
 * 通用请求
 */
public abstract class UniversalApi<T> extends AbstractFrameApi<T> {

    /**
     * 参数
     */
    private final ArrayMap<String, Object> params;

    /**
     * @param tag               请求标签：Activity.class、Fragment.class、Service.class等等；
     * @param aClass            Gson解析目标实体；
     * @param iResponseListener 响应监听；
     */
    public UniversalApi(Class<?> tag, Class<T> aClass, IResponseListener<T> iResponseListener) {
        super(tag, aClass, iResponseListener);
        params = new ArrayMap<>();
    }

    /**
     * 设置请求参数
     */
    protected abstract void setParams();

    /**
     * 添加参数
     */
    protected void putParams(String key, Object value) {
        params.put(key, value);
    }

    /**
     * 清空参数
     */
    protected void resetParams() {
        params.clear();
    }

    @Override
    public byte[] params() {
        if (getMethod() == Request.Method.POST) {
            Logger.t(ILoggerTag.FRAME_REQUEST).d("request params : %s", new Gson().toJson(params));
            return new ArrayMapEncode(params).encode(getParamsEncoding());
        } else {
            return null;
        }
    }

    @Override
    public StringBuilder url() {
        final String path = getPath();
        final int method = getMethod();
        StringBuilder urlBuilder = new StringBuilder();
        urlBuilder.append(getIp());
        if (TextUtils.isEmpty(path)) {
            Logger.t(ILoggerTag.FRAME_REQUEST).d("method: %s", new VolleyMethodToString(method).parse2Sting());
        } else {
            urlBuilder.append(path);
            Logger.t(ILoggerTag.FRAME_REQUEST).d("method: %s\npath : %s", new VolleyMethodToString(method).parse2Sting(), path);
        }
        setParams();
        switch (method) {
            case Request.Method.GET:
            case Request.Method.DELETE:
                if (!params.isEmpty()) {
                    Logger.t(ILoggerTag.FRAME_REQUEST).d("params : %s", new Gson().toJson(params));
                    urlBuilder.append("?");
                    final String paramsEncoding = getParamsEncoding();
                    try {
                        for (Map.Entry<String, Object> entry : params.entrySet()) {
                            urlBuilder.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
                            urlBuilder.append('=');
                            urlBuilder.append(URLEncoder.encode(String.valueOf(entry.getValue()), paramsEncoding));
                            urlBuilder.append('&');
                        }
                    } catch (UnsupportedEncodingException e) {
                        throw new RuntimeException("Encoding not supported: " + paramsEncoding, e);
                    }
                    urlBuilder.deleteCharAt(urlBuilder.length() - 1);
                }
                break;
            default:
                break;
        }
        Logger.t(ILoggerTag.FRAME_REQUEST).d("url : %s", urlBuilder.toString());
        return urlBuilder;
    }
}
